/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package percussiongenerator.gui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.HashMap;
import javax.sound.midi.Instrument;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.jfonia.connect5.relations.ABRelation;
import org.jfonia.connect5.relations.Equal;
import percussiongenerator.commands.CommandHistory;
import percussiongenerator.commands.RemoveTrack;
import percussiongenerator.gui.view.LeadSheetView;
import percussiongenerator.gui.view.MetronomeView;
import percussiongenerator.gui.view.PianorollView;
import percussiongenerator.gui.view.TimeLineView;
import percussiongenerator.gui.view.View;
import percussiongenerator.gui.view.ViewOptionsPanel;
import percussiongenerator.model.Track;
import percussiongenerator.sound.SimpleInstrument;

/**
 *
 * @author jannes
 */
public class TrackOptionsPanel extends JPanel{
    private ArrayList<ABRelation> relations;
    private ViewOptionsPanel viewOptionsPanel;    
    public TrackOptionsPanel(final Track track,View view, Instrument[] instruments){
        relations = new ArrayList<ABRelation>();
        this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        viewOptionsPanel = view.getViewOptions();
        final JCheckBox chbShowViewOptions = new JCheckBox("Show view options");
        chbShowViewOptions.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                if(chbShowViewOptions.isSelected()){
                    viewOptionsPanel.setVisible(true);
                }else{
                    viewOptionsPanel.setVisible(false);
                }
            }
        });
        this.add(viewOptionsPanel);
        this.add(new JSeparator());
        if(!(view instanceof MetronomeView)){
            Box box = Box.createHorizontalBox();
            this.add(box);
            JButton btnRemoveTrack = new JButton("Remove track");
            box.add(btnRemoveTrack);
            box.add(Box.createHorizontalGlue());
            btnRemoveTrack.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    CommandHistory.addCommandAndExecute(new RemoveTrack(track));
                }
            });
        }        
        Box container = Box.createVerticalBox();
        container.setBorder(BorderFactory.createTitledBorder("Sound"));
        Box box = Box.createHorizontalBox();
        this.add(container);
        container.add(box);
        container.add(Box.createVerticalStrut(5));
        final JCheckBox chbMute = new JCheckBox("Mute");
        box.add(chbMute);
        box.add(Box.createHorizontalGlue());
        chbMute.setSelected(track.isMuted());
        chbMute.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                track.setMute(chbMute.isSelected());
            }
        });       
        box = Box.createHorizontalBox();
        container.add(box);        
        ChooseInstrumentPanel instrumentPanel = new ChooseInstrumentPanel(instruments);
        box.add(instrumentPanel);
        box.add(Box.createHorizontalGlue());
        relations.add(new Equal<SimpleInstrument>(track.getInstrumentNode(),instrumentPanel.getSelectedInstrumentNode()));        
        this.add(Box.createVerticalStrut(5));
        if(!(view instanceof MetronomeView)){         
            HashMap<Class,JCheckBox> checkboxes = new HashMap<Class, JCheckBox>();
            container = Box.createVerticalBox();
            box = Box.createHorizontalBox();
            this.add(box);
            box.setBorder(BorderFactory.createTitledBorder("Views"));
            box.add(container);
            box.add(Box.createHorizontalGlue());
            final JCheckBox chbSimpleView = new JCheckBox("Times");
            checkboxes.put(TimeLineView.class,chbSimpleView);
            chbSimpleView.setAlignmentX(0f);
            //container.add(chbSimpleView);
            final JCheckBox chbPianoroll= new JCheckBox("Pianoroll");
            checkboxes.put(PianorollView.class,chbPianoroll);
            container.add(chbPianoroll);
            final JCheckBox chbLeadSheet = new JCheckBox("Notes");
            checkboxes.put(LeadSheetView.class, chbLeadSheet);
            container.add(chbLeadSheet);
            //set values of checkboxes;
            final TrackPanel trackPanel = ((TrackPanel)view.getParent());
            ArrayList<View> views = trackPanel.getViews();
            for(View v : views){
                JCheckBox chb = checkboxes.get(v.getClass());
                if(chb != null){
                    chb.setSelected(true);
                }                        
            }
            
            for(Class c : checkboxes.keySet()){
                JCheckBox chb = checkboxes.get(c);
                chb.addChangeListener(new ChangeListenerViewBoxes(c, checkboxes, trackPanel));
            }            
            box = Box.createHorizontalBox();            
        }
       
        this.add(Box.createVerticalGlue());
    }

    public void removeRelations(){
        for(int i = 0; i < relations.size(); i++){
            relations.get(i).switchOff();
        }
        relations = new ArrayList<ABRelation>();
        viewOptionsPanel.removeRelations();
    }

    private class ChangeListenerViewBoxes implements ChangeListener{
        private Class c;
        private HashMap<Class,JCheckBox> checkboxes;
        private TrackPanel trackPanel;

        public ChangeListenerViewBoxes(Class c,HashMap<Class,JCheckBox> checkboxes,TrackPanel trackPanel){
            this.c = c;
            this.checkboxes = checkboxes;
            this.trackPanel = trackPanel;
            updateCheckBoxes(checkboxes.get(c));
        }

        public void updateCheckBoxes(JCheckBox chb){
            ArrayList<JCheckBox> boxes = new ArrayList<JCheckBox>();
            for(JCheckBox box: checkboxes.values()){
                if(box.isSelected()){
                    boxes.add(box);
                }
            }
            if(chb.isSelected()){
                trackPanel.addView(c);
                if(boxes.size() > 1){
                    for(JCheckBox box: checkboxes.values()){
                        box.setEnabled(true);
                    }
                }
            }else{
                trackPanel.removeView(c);
                if(boxes.size() == 1){                    
                    boxes.get(0).setEnabled(false);
                }
            }
        }

        public void stateChanged(ChangeEvent e) {
            JCheckBox chb = (JCheckBox)e.getSource();
            updateCheckBoxes(chb);
        }
        
    }
}
